home *** CD-ROM | disk | FTP | other *** search
/ 10,000 Great Games / 10,000 Great Games.iso / Product / 66 / data1.cab / Source_Files / Src / Primitives.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  5KB  |  247 lines

  1. #include "stdafx.h"
  2.  
  3. static cSurface *locked_surface;
  4. static DDSURFACEDESC2 desc;
  5.  
  6. static void (*_pixel)(int x, int y, int color);
  7.  
  8. void _pixel8(int x, int y, int color)
  9. {
  10.     if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
  11.         *((BYTE *)desc.lpSurface + x + y * desc.lPitch) = (BYTE)color;
  12. }
  13.  
  14. void _pixel16(int x, int y, int color)
  15. {
  16.     if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
  17.         *(WORD *)((BYTE *)desc.lpSurface + (x << 1) + y * desc.lPitch) = (WORD)color;
  18. }
  19.  
  20. void _pixel24(int x, int y, int color)
  21. {
  22.     if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
  23.     {
  24.         BYTE *d = (BYTE *)desc.lpSurface + (x << 1) + x + y * desc.lPitch;
  25.         *(WORD *)d = (WORD)color, d[2] = (BYTE)(color >> 16);
  26.     }
  27. }
  28.  
  29. void _pixel32(int x, int y, int color)
  30. {
  31.     if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
  32.         *(DWORD *)((BYTE *)desc.lpSurface + (x << 2) + y * desc.lPitch) = (DWORD)color;
  33. }
  34.  
  35. void lock_surface_for_primitives(cSurface *surface)
  36. {
  37.     desc.dwSize = sizeof(desc);
  38.     
  39.     while (!draw_ok(surface->dds->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
  40.  
  41.     locked_surface = surface;
  42.  
  43.     switch(desc.ddpfPixelFormat.dwRGBBitCount)
  44.     {
  45.     case 8:
  46.         _pixel = _pixel8;
  47.         break;
  48.  
  49.     case 16:
  50.         _pixel = _pixel16;
  51.         break;
  52.  
  53.     case 24:
  54.         _pixel = _pixel24;
  55.         break;
  56.  
  57.     case 32:
  58.         _pixel = _pixel32;
  59.         break;
  60.     }
  61. }
  62.  
  63. void unlock_surface_for_primitives()
  64. {
  65.     locked_surface->dds->Unlock(0);
  66. }
  67.  
  68. void pixel(cSurface *surface, int x, int y, int color)
  69. {
  70.     // Go to surface coordinates
  71.  
  72.     x = locked_surface->x_screen(x);
  73.     y = locked_surface->y_screen(y - surface->start + locked_surface->start);
  74.  
  75.     // Draw the pixel
  76.  
  77.     _pixel(x, y, color);
  78. }
  79.  
  80. void hline(cSurface *surface, int x1, int y1, int x2, int color)
  81. {
  82.     // Go to surface coordinates
  83.  
  84.     x1 = locked_surface->x_screen(x1);
  85.     x2 = locked_surface->x_screen(x2);
  86.     y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
  87.  
  88.     // x1 is lowest
  89.  
  90.     sort2(x1, x2);
  91.  
  92.     // Draw the line
  93.  
  94.     for (int x = x1; x <= x2; x++)
  95.         _pixel(x, y1, color);
  96. }
  97.  
  98. void vline(cSurface *surface, int x1, int y1, int y2, int color)
  99. {
  100.     // Go to surface coordinates
  101.  
  102.     x1 = locked_surface->x_screen(x1);
  103.     y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
  104.     y2 = locked_surface->y_screen(y2 - surface->start + locked_surface->start);
  105.  
  106.     // y1 is lowest
  107.  
  108.     sort2(y1, y2);
  109.  
  110.     // Draw the line
  111.  
  112.     for (int y = y1; y <= y2; y++)
  113.         _pixel(x1, y, color);
  114. }
  115.  
  116. void rect(cSurface *surface, int x1, int y1, int x2, int y2, int color)
  117. {
  118.     hline(surface, x1, y1, x2, color);
  119.     hline(surface, x1, y2, x2, color);
  120.     vline(surface, x1, y1, y2, color);
  121.     vline(surface, x2, y1, y2, color);
  122. }
  123.  
  124. void rectfill(cSurface *surface, int x1, int y1, int x2, int y2, int color)
  125. {
  126.     sort2(y1, y2);
  127.  
  128.     for (int y = y1; y <= y2; y++)
  129.         hline(surface, x1, y, x2, color);
  130. }
  131.  
  132. void line(cSurface *surface, int x1, int y1, int x2, int y2, int color)
  133. {
  134.     // Go to surface coordinates
  135.  
  136.     x1 = locked_surface->x_screen(x1);
  137.     x2 = locked_surface->x_screen(x2);
  138.     y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
  139.     y2 = locked_surface->y_screen(y2 - surface->start + locked_surface->start);
  140.     
  141.     // Get size in x and y direction
  142.  
  143.     int sx = abs(x2 - x1), sy = abs(y2 - y1), p;
  144.     
  145.     // Determine how many pixels to write
  146.  
  147.     if (sx > sy)
  148.         p = sx;
  149.     else
  150.         p = sy;
  151.  
  152.     // Check if there is anything to draw
  153.  
  154.     if (p == 0)
  155.         return;
  156.  
  157.     // Set initial position and compute delta
  158.  
  159.     fix x = x1, y = y1, dx = (fix)(x2 - x1) / p, dy = (fix)(y2 - y1) / p;
  160.  
  161.     // Draw the line
  162.  
  163.     for (int i = 0; i <= p; i++)
  164.     {
  165.         _pixel((int)x, (int)y, color);
  166.  
  167.         x += dx, y += dy;
  168.     }
  169. }
  170.  
  171. void dashedline(cSurface *surface, int x1, int y1, int x2, int y2, int color)
  172. {
  173.     // Go to surface coordinates
  174.  
  175.     x1 = locked_surface->x_screen(x1);
  176.     x2 = locked_surface->x_screen(x2);
  177.     y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
  178.     y2 = locked_surface->y_screen(y2 - surface->start + locked_surface->start);
  179.  
  180.     // Get size in x and y direction
  181.  
  182.     int sx = abs(x2 - x1), sy = abs(y2 - y1), p;
  183.  
  184.     // Determine how many pixels to write
  185.  
  186.     if (sx > sy)
  187.         p = sx >> 2;
  188.     else
  189.         p = sy >> 2;
  190.  
  191.     // Check if there is anything to draw
  192.  
  193.     if (p == 0)
  194.         return;
  195.  
  196.     // Set initial position and compute delta
  197.  
  198.     fix x = x1, y = y1, dx = (fix)(x2 - x1) / p, dy = (fix)(y2 - y1) / p;
  199.  
  200.     // Draw the line
  201.  
  202.     for (int i = 0; i <= p; i++)
  203.     {
  204.         _pixel((int)x, (int)y, color);
  205.  
  206.         x += dx, y += dy;
  207.     }
  208. }
  209.  
  210. void circle(cSurface *surface, int x, int y, int r, int color)
  211. {
  212.     // Go to surface coordinates
  213.  
  214.     x = locked_surface->x_screen(x);
  215.     y = locked_surface->y_screen(y - surface->start + locked_surface->start);
  216.     
  217.     // Declare some variables
  218.     
  219.     fix angle;
  220.     int dx, dy;
  221.  
  222.     // Pixels to write is 2*Pi*r but we compute only 1/4 of the circle
  223.  
  224.     int p = 11 * r / 7;
  225.  
  226.     // Write circle
  227.  
  228.     for (int i = 0; i <= p; i++)
  229.     {
  230.         // Step through angle from 0 to 1/2 * Pi = 64 in fixed point
  231.  
  232.         fix angle = (fix)(i * 63 / p);
  233.  
  234.         // Compute location of dot
  235.  
  236.         dx = (int)(cos(angle) * r);
  237.         dy = (int)(sin(angle) * r);
  238.  
  239.         // Write 4 dots at once
  240.  
  241.         _pixel(x + dx, y + dy, color);
  242.         _pixel(x + dx, y - dy, color);
  243.         _pixel(x - dx, y + dy, color);
  244.         _pixel(x - dx, y - dy, color);
  245.     }
  246. }
  247.